package com.ywjh.inter.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;

import com.ywjh.inter.conn.DBConnection;
import com.ywjh.inter.dao.UserMedPlanDAO;
import com.ywjh.inter.dao.UserMedPlanMedDAO;
import com.ywjh.inter.entity.DocMedicineEntity;
import com.ywjh.inter.entity.UserMedPlanEntity;
import com.ywjh.inter.entity.UserMedPlanMedEntity;
import com.ywjh.inter.utils.StrUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class MedPlanService {
	private static MedPlanService instance;
	private UserMedPlanDAO userMedPlanDAO;
	private UserMedPlanMedDAO userMedPlanMedDAO;
	private Map<Integer, DocMedicineEntity> medMap;

	public static MedPlanService getInstance() {
		if (instance == null) {
			instance = new MedPlanService();
			instance.userMedPlanDAO = new UserMedPlanDAO();
			instance.userMedPlanMedDAO = new UserMedPlanMedDAO();
			instance.medMap = initMed();
		}
		return instance;
	}

	public DocMedicineEntity findMedById(int medId) {
		return medMap.get(medId);
	}

	private static Map<Integer, DocMedicineEntity> initMed() {
		Map<Integer, DocMedicineEntity> map = new HashedMap();
		JSONArray array = DocService.getInstance().getMedicine();
		for (int i = 0; i < array.size(); i++) {
			JSONObject json = array.getJSONObject(i);
			JSONArray medArray = json.getJSONArray("med_array");
			for (int j = 0; j < medArray.size(); j++) {
				JSONObject medJson = medArray.getJSONObject(j);
				DocMedicineEntity medEntity = new DocMedicineEntity();
				try {
					medEntity.setId(medJson.getInt("id"));
					medEntity.setName(medJson.getString("name"));
					medEntity.setUnit(medJson.getString("unit"));
					medEntity.setDrugusage(medJson.getString("usage"));
					map.put(medEntity.getId(), medEntity);
				} catch (Exception e) {
				}
			}
		}
		return map;
	}

	public int addUserMedPlan(UserMedPlanEntity entity, JSONArray medArray) {
		int id = -1;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			conn.setAutoCommit(false);
			entity.setEnd_time(getMedPlanEndTime(entity.getStart_time(), entity.getPeriod(), entity.getPeriod_unit(),
					entity.getWeek_day()));
			id = userMedPlanDAO.insert(conn, entity);
			if (id > 0) {
				List<UserMedPlanMedEntity> list = new LinkedList<UserMedPlanMedEntity>();
				for (int i = 0; i < medArray.size(); i++) {
					JSONObject medObj = medArray.getJSONObject(i);
					UserMedPlanMedEntity medPlanMedEntity = new UserMedPlanMedEntity();
					medPlanMedEntity.setCount(medObj.getInt("count"));
					medPlanMedEntity.setMed_id(medObj.getInt("med_id"));
					medPlanMedEntity.setMed_plan_id(id);
					medPlanMedEntity.setTime(medObj.getString("time"));
					list.add(medPlanMedEntity);
				}
				userMedPlanMedDAO.set(conn, list, id);
				conn.commit();
			} else {
				conn.rollback();
			}
		} catch (ClassNotFoundException | SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DBConnection.close(conn);
		}
		return id;
	}

	public boolean updateUserMedPlan(UserMedPlanEntity entity, JSONArray medArray) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			conn.setAutoCommit(false);
			entity.setEnd_time(getMedPlanEndTime(entity.getStart_time(), entity.getPeriod(), entity.getPeriod_unit(),
					entity.getWeek_day()));

			b = userMedPlanDAO.update(conn, entity);
			if (b && medArray != null) {
				List<UserMedPlanMedEntity> list = new LinkedList<UserMedPlanMedEntity>();
				for (int i = 0; i < medArray.size(); i++) {
					JSONObject medObj = medArray.getJSONObject(i);
					UserMedPlanMedEntity medPlanMedEntity = new UserMedPlanMedEntity();
					medPlanMedEntity.setCount(medObj.getInt("count"));
					medPlanMedEntity.setMed_id(medObj.getInt("med_id"));
					medPlanMedEntity.setMed_plan_id(entity.getId());
					medPlanMedEntity.setTime(medObj.getString("time"));
					list.add(medPlanMedEntity);
				}
				userMedPlanMedDAO.set(conn, list, entity.getId());
				conn.commit();
			} else {
				conn.rollback();
			}
		} catch (ClassNotFoundException | SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DBConnection.close(conn);
		}
		return b;
	}

	public List<UserMedPlanEntity> findMedPlanByUserId(int userId) {
		List<UserMedPlanEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = userMedPlanDAO.listByUserId(conn, userId);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public List<UserMedPlanEntity> findMedPlanByDocId(int docId) {
		List<UserMedPlanEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = userMedPlanDAO.listByDocId(conn, docId);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public UserMedPlanEntity findMedPlanById(int id) {
		UserMedPlanEntity entity = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			entity = userMedPlanDAO.findById(conn, id);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return entity;
	}

	/**
	 * 计算计划结束日期
	 * @param startTime 计划开始事件
	 * @param period 循环周期 
	 * @param unit 循环单位
	 * @param week_day 执行星期
	 * @return
	 */
	private Timestamp getMedPlanEndTime(Timestamp startTime, int period, String unit, String week_day) {
		List<Integer> dayWeekList = new LinkedList<Integer>();
		for (String d : week_day.split(",")) {
			dayWeekList.add(Integer.parseInt(d));
		}
		if (UserMedPlanEntity.DAY.equals(unit)) {
			System.out.println(11111);
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(startTime.getTime());
			while (true) {
				cal.add(Calendar.DATE, 1);
				if (dayWeekList.contains(cal.get(Calendar.DAY_OF_WEEK))) {
					System.out.println("get=" + new Timestamp(cal.getTimeInMillis()));
					period--;
					if (period == 0) {
						break;
					}
				}
			}
			return new Timestamp(cal.getTimeInMillis());
		}
		if (UserMedPlanEntity.WEEK.equals(unit)) {
			System.out.println(2222222);
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(startTime.getTime());
			Collections.sort(dayWeekList);
			int lastday = dayWeekList.get(dayWeekList.size() - 1);
			System.out.println("last check==" + lastday);
			cal.add(Calendar.WEEK_OF_YEAR, period);
			cal.set(Calendar.DAY_OF_WEEK, lastday);
			return new Timestamp(cal.getTimeInMillis());
		}
		if (UserMedPlanEntity.MONTH.equals(unit)) {
			System.out.println(333333);
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(startTime.getTime());
			Collections.sort(dayWeekList);
			int lastday = dayWeekList.get(dayWeekList.size() - 1);
			cal.add(Calendar.MONTH, period);
			cal.set(Calendar.DAY_OF_WEEK, lastday);
			return new Timestamp(cal.getTimeInMillis());
		}
		return null;
	}


	public List<UserMedPlanMedEntity> listMedByPlanId(int id) {
		List<UserMedPlanMedEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = userMedPlanMedDAO.listByPlanId(conn, id);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public void deleteUserMedPlan(UserMedPlanEntity entity) {
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			userMedPlanMedDAO.deleteByPlanId(conn, entity.getId());
			userMedPlanDAO.deleteById(conn, entity.getId());
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
	}

	public long nextTime(UserMedPlanEntity entity,String hhmi) {
		long t = 0l;
		if (entity == null) {
			return t;
		}
		Calendar startCal=Calendar.getInstance();
		startCal.setTimeInMillis(entity.getStart_time().getTime());
		startCal.set(Calendar.SECOND, 0);
		startCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hhmi.split(":")[0]));
		startCal.set(Calendar.MINUTE, Integer.parseInt(hhmi.split(":")[1]));
		if (startCal.getTimeInMillis() > System.currentTimeMillis()) {
			System.out.print("未到计划开始时间，返回 当前时间与计划开始时间差");
			return entity.getStart_time().getTime() - System.currentTimeMillis();
		}
		String[] weekDay = entity.getWeek_day().split(",");
		int i = 0;
		while (true) {
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.HOUR_OF_DAY, startCal.get(Calendar.HOUR_OF_DAY));
			cal.set(Calendar.MINUTE, startCal.get(Calendar.MINUTE));
			cal.set(Calendar.SECOND, startCal.get(Calendar.SECOND));
			cal.add(Calendar.DATE, i);
			String currentWD = cal.get(Calendar.DAY_OF_WEEK) + "";
			for (String planWD : weekDay) {
				if (currentWD.equals(planWD)) {
					System.out.println("配置weekday"+entity.getWeek_day()+" :找到 "+StrUtil.getYYYYMMDDHHMISS(new Timestamp(cal.getTimeInMillis()))+" current wd="+currentWD);
					return t = cal.getTimeInMillis() - System.currentTimeMillis();
				}
			}
			if (cal.getTimeInMillis() > entity.getEnd_time().getTime()) {
				break;
			} else {
				i++;
			}
		}
		return t;
	}
	
	public static void main(String[] args) {
		UserMedPlanEntity medPlanEntity=new UserMedPlanEntity();
		medPlanEntity.setAdd_time(new Timestamp(System.currentTimeMillis()));
		medPlanEntity.setDoc_id(5);
		medPlanEntity.setPeriod_unit(UserMedPlanEntity.WEEK);
		medPlanEntity.setPeriod(3);
		medPlanEntity.setStart_time(StrUtil.getTimestampHHMISS("2021-11-10 10:30:00"));
		medPlanEntity.setStatus(1);
		medPlanEntity.setWeek_day("2,4,6,7");
		Timestamp t1 = getInstance().getMedPlanEndTime(medPlanEntity.getStart_time(),medPlanEntity.getPeriod(),
				medPlanEntity.getPeriod_unit(), medPlanEntity.getWeek_day());
		medPlanEntity.setEnd_time(t1);
		System.out.println(medPlanEntity);
		long bw=getInstance().nextTime(medPlanEntity,"10:30")/1000;
		System.out.println(bw);
		System.out.println(getInstance().formatDateTime( bw));
	}
	public String formatDateTime(long mss) {
		String DateTimes = null;
		long days = mss / ( 60 * 60 * 24);
		long hours = (mss % ( 60 * 60 * 24)) / (60 * 60);
		long minutes = (mss % ( 60 * 60)) /60;
		long seconds = mss % 60;
		if(days>0){
			DateTimes= days + "天" + hours + "小时" + minutes + "分钟"
					+ seconds + "秒";
		}else if(hours>0){
			DateTimes=hours + "小时" + minutes + "分钟"
					+ seconds + "秒";
		}else if(minutes>0){
			DateTimes=minutes + "分钟"
					+ seconds + "秒";
		}else{
			DateTimes=seconds + "秒";
		}

		return DateTimes;
	}
}
